package com.example.project.filter;

import com.example.project.utils.JwtUtil;
import com.example.project.utils.UserContextUtil;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.lang.NonNull;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.filter.OncePerRequestFilter;

import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;
import java.util.Base64;

/**
 * JWT认证过滤器，解析 JWT 并存入 ThreadLocal
 */
@Slf4j
public class JwtAuthenticationFilter extends OncePerRequestFilter {

    private static final String TOKEN_PREFIX = "Bearer ";
    private static final String HEADER_STRING = "Authorization";

    @Resource
    private JwtUtil jwtUtil;

    @Override
    protected void doFilterInternal(HttpServletRequest request, @NonNull HttpServletResponse response, @NonNull FilterChain filterChain)
            throws ServletException, IOException {
        String header = request.getHeader(HEADER_STRING);

        // 如果没有Authorization头或不是Bearer令牌，不设置认证信息，直接交给Spring Security
        if (header == null || !header.startsWith(TOKEN_PREFIX)) {
            filterChain.doFilter(request, response); // 放行，依赖SecurityConfig的authenticated()
            return;
        }

        // 提取并验证JWT
        String token = header.replace(TOKEN_PREFIX, "");
        try {
            // 从JWT中获取用户名
            String username = jwtUtil.getUsernameFromToken(token);
            if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
                setAuthentication(username); // 设置认证信息,并且将用户名存入ThreadLocal
//                log.info("<JWT验证>  用户名:{}", UserContextUtil.getUser());
            }
            // 认证成功后才放行
            filterChain.doFilter(request, response);
        } catch (Exception e) {
            log.warn("<系统异常:JWT验证>  状态码:{}, 异常消息:{}",
                    HttpStatus.INTERNAL_SERVER_ERROR.value(),
                    e.getMessage());
        } finally {
            UserContextUtil.clear();
        }
    }

    /**
     * 设置认证信息到 SecurityContextHolder
     * @param username 用户名
     */
    private void setAuthentication(String username) {
        UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(
                username, null, null);
        SecurityContextHolder.getContext().setAuthentication(auth);
        // 将用户登录的信息存入 ThreadLocal
        UserContextUtil.setUser(username);
    }
}